﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace IHM
{
    /// <summary>
    /// Logique d'interaction pour MainWindow.xaml
    /// </summary>
    public partial class MapWindow : Window
    {
        Partie jeu;
        Carte map;


        public MapWindow()
        {
            InitializeComponent();
            jeu = new Partie(25, 2);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // on initialise la Grid (mapGrid défini dans le xaml) à partir de la map du modèle (engine)
            map = jeu.carte;
            for (int c = 0; c < map.largeur; c++)
            {
                mapGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(50, GridUnitType.Pixel) });
                mapGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(50, GridUnitType.Pixel) });
            }
            for (int l = 0; l < map.largeur; l++)
            {
                for (int c = 0; c < map.largeur; c++)
                {
                    // dans chaque case de la grille on ajoute une tuile (logique) matérialisée par un rectangle (physique)
                    // le rectangle possède une référence sur sa tuile
                    var tile = map.cases[c, l];
                    var element = createRectangle(c, l, tile);
                    mapGrid.Children.Add(element);
                }
            }
            //updateUnitUI();
        }

        private Rectangle createRectangle(int c, int l, Case tile)
        {
            var rectangle = new Rectangle();
            if (tile is Plaine)
                rectangle.Fill = Brushes.DarkGreen;
            if (tile is Montagne)
                rectangle.Fill = Brushes.SlateBlue;
            if (tile is Desert)
                rectangle.Fill = Brushes.Brown;
            // mise à jour des attributs (column et Row) référencant la position dans la grille à rectangle
            Grid.SetColumn(rectangle, c);
            Grid.SetRow(rectangle, l);
            rectangle.Tag = tile; // Tag : ref par defaut sur la tuile logique

            rectangle.Stroke = Brushes.Red;
            rectangle.StrokeThickness = 1;
            // enregistrement d'un écouteur d'evt sur le rectangle : 
            // source = rectangle / evt = MouseLeftButtonDown / délégué = rectangle_MouseLeftButtonDown
            rectangle.MouseLeftButtonDown += new MouseButtonEventHandler(rectangle_MouseLeftButtonDown);
            return rectangle;
        }

        void rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var rectangle = sender as Rectangle;
            var tile = rectangle.Tag as Case;

            int column = Grid.GetColumn(rectangle);
            int row = Grid.GetRow(rectangle);

            // V2 : gestion avec Binding
            // Mise à jour du rectangle selectionné => le label sera mis à jour automatiquement par Binding
            Grid.SetColumn(selectionRectangle, column);
            Grid.SetRow(selectionRectangle, row);
            selectionRectangle.Tag = tile;
            selectionRectangle.Visibility = System.Windows.Visibility.Visible;

            // V1 : gestion avec evts classiques
            //if (selectedVisual != null)
            //    selectedVisual.StrokeThickness = 1;
            //selectedVisual = rectangle;
            //selectedVisual.Tag = tile; // Tag : ref par defaut sur la tuile logique
            //rectangle.StrokeThickness = 3;
            //infoLabel.Content = String.Format("[{0:00} - {1:00}] {2} Fer : {3}", column, row, tile, tile.Iron);

            // on arrête la propagation d'evt : sinon l'evt va jusqu'à la fenetre => affichage via "Window_MouseLeftButtonDown"
            e.Handled = true;
        }

        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // V1 : gestion avec evts classiques
            //infoLabel.Content = "Pas d'info";
            //if (selectedVisual != null)
            //    selectedVisual.StrokeThickness = 0;
            //selectedVisual = null;

            // V2 : gestion avec Binding
            // on cache(enlève) le rectangle de selection 
            // la réf sur la tuile est mise à null
            selectionRectangle.Tag = null;
            selectionRectangle.Visibility = System.Windows.Visibility.Collapsed;
        }


        /// <summary>
        /// Délégué : réaction à l'evt : clic sur le bouton "prochain tour"
        /// </summary>
        /// <param name="sender"> le bouton "tour suivant" </param>
        /// <param name="e"></param>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // création d'un thread pour lancer le calcul du tour suivant sans que cela soit bloquant pour l'IHM
            Task.Factory.StartNew(() =>
            {

                
                //jeu.NextTurn(); // calcul du prochain tour
                // appel de méthodes dand un autre thread : le thread principal (de l'IHM) : 
                this.Dispatcher.BeginInvoke(new Action(() =>
                {
                    //updateUnitUI();

                    // V1 : gestion avec evts classiques
                    //int column = Grid.GetColumn(selectedVisual);
                    //int row = Grid.GetRow(selectedVisual);
                    //var tile = selectedVisual.Tag as ITile;
                    //int iron = tile.Iron;
                    //infoLabel.Content = String.Format("[{0:00} - {1:00}] {2} Fer : {3}", column, row, tile, iron);            

                    // V2 : gestion avec Binding
                    // On "touche" au rectangle de selection pour provoquer un rafraichissemnt via le Binding
                    var selected = selectionRectangle.Tag;
                    selectionRectangle.Tag = null;
                    selectionRectangle.Tag = selected;
                }));
            });

        }


    }
}
